#include "stdafx.h"
#include <boost/test/auto_unit_test.hpp>
#include "bmock.hpp"
#include <iostream>

struct my_fd_set {
	unsigned int fd_count;
	unsigned int fd_array[100];

};

namespace std {
	static ostream& operator<<(ostream& os, const my_fd_set& fdset) {
		os << fdset.fd_count;
		for(unsigned int i=0; i != fdset.fd_count; i++) 
			os << " " << fdset.fd_array[i];
		return os;
	}

	static istream& operator>>(istream& s, my_fd_set& fdset) {
		s >> fdset.fd_count;
		for(unsigned int i=0; i != fdset.fd_count; i++) {
			char c;
			s >> c >> fdset.fd_array[i];
		}
		return s;
	}
}

typedef my_fd_set test_data;
inline bool operator ==(const my_fd_set &f1,const my_fd_set &f2) {
	if (f1.fd_count != f2.fd_count) return false;
	return std::equal(f1.fd_array,f1.fd_array+f1.fd_count,f2.fd_array);
}

static void f(int* x, int* y, test_data* z) {
	MOCK_VOID(3,(IN(x),OUT(y),IN_OUT(z)));
}

static test_data z_in  = {1,{1}};
static test_data z_out = {3,{1,1,1}};

struct in_out_ptr_tester2 {
	static const int x_in  = 11;
	static const int y_out = 23;
	in_out_ptr_tester2()
		:x_(x_in)
		,y_(y_out)
		,z_(z_in)
	{
		BMOCK_CREATE_MOCK(*);
	}
	~in_out_ptr_tester2() {
		BMOCK_REPLAY;
		BOOST_CHECK_NO_THROW(f(&x_,&y_,&z_));
		BMOCK_VERIFY;
		BOOST_CHECK_EQUAL(x_in,x_);
		BOOST_CHECK_EQUAL(y_out,y_);
		BOOST_CHECK_EQUAL(z_out,z_);
	}
	int       x_;
	int       y_;
	test_data z_;
};

const int in_out_ptr_tester2::x_in;
const int in_out_ptr_tester2::y_out;


BMOCK_TEST(in_out_ptr_tester2,test_reference) {
	BOOST_CHECK_NO_THROW(BMOCK_EXPECT(f(
		&x_
		,&y_
		,bmock::in_out_raw_mem(z_in,z_out)
		)));
}

BMOCK_TEST(in_out_ptr_tester2,test_pointer) {
	BOOST_CHECK_NO_THROW(BMOCK_EXPECT(f(
		&x_
		,&y_
		,bmock::in_out_raw_mem(&z_in,&z_out)
		)));
}
